package com.java.mall_imooc.interceoter;

import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.java.mall_imooc.common.enums.ResultEnum;
import com.java.mall_imooc.common.utils.*;
import com.java.mall_imooc.config.JwtProperties;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author jl
 * @since 2020-03-14 23:41:10
 * 1.定义login拦截器
 * 2.注册自定义拦截器
 */
@Component
@AllArgsConstructor
public class LoginInterceptor extends HandlerInterceptorAdapter {
    private JwtProperties jwtProperties;

    private static final Gson gson = new Gson();

    private static final ThreadLocal<JwtUserInfo> THREAD_LOCAL = new ThreadLocal<>();

    /**
     * true表示继续流程  false表示中断
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取token
        String token = CookieUtils.getCookieValue(request, jwtProperties.getCookieName());
        if (StrUtil.isEmpty(token)) {
            sendJsonMessage(response, R.error(ResultEnum.NEED_LOGIN));
            return false;
        }
        // 解析token,获取用户信息
        JwtUserInfo jwtUserInfo = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey());
        if (jwtUserInfo.getUserId() == null) {
            sendJsonMessage(response, R.error(ResultEnum.RE_LOGIN));
            return false;
        }
        // 用户信息存放到线程局部变量ThreadLocal,可以在Controller、Service中取出
        THREAD_LOCAL.set(jwtUserInfo);
        // 用户每请求一次就刷新token有效期,保持登录状态
        CookieUtils.setCookie(request,response,jwtProperties.getCookieName(),token,jwtProperties.getCookieMaxAge());
        return true;
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清空线程局部变量.因为使用的是tomcat的线程池,线程不会结束,也就不会自动释放局部变量.
        THREAD_LOCAL.remove();
    }

    public static JwtUserInfo getUserInfo() {
        return THREAD_LOCAL.get();
    }

    /**
     * 响应数据给前端
     */
    public static void sendJsonMessage(HttpServletResponse response, Object obj) throws IOException {

        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(gson.toJson(obj));
        writer.close();

        response.flushBuffer();

    }

}
